﻿// ....................................................................................................................
//	Author: Copyright (C) 2012 Ing. Marek Hubal
//	Email: hubal@acasoftware.org
// ....................................................................................................................

using System;

namespace core
{
    /// <summary>Trieda IParamList</summary>
	public class IParamList : IDisposable
	{
        protected System.Collections.Generic.Dictionary<string, string> FParams; // Zoznam parametrov

        /// <summary>Property: Count</summary>
        public int Count
        {
            get
            {
                return FParams.Count;
            }
        }

        /// <summary>Konstruktor</summary>
        public IParamList()
        {
            FParams = new System.Collections.Generic.Dictionary<string, string>();
        }
        /// <summary>Dispose metoda</summary>
        public void Dispose()
        {
            if (FParams != null)
            {
                FParams.Clear(); FParams = null;
            }
        }

        /// <summary>Vymazanie obsahu</summary>
        public void Clear()
        {
            FParams.Clear();
        }
        /// <summary>Skopirovanie obsahu objektu</summary>
        /// <param name="pValue">objekt pre skopirovanie</param>
        public void Assign(IParamList pValue)
        {
            FParams.Clear(); // Zmazem aktualny obsah
            foreach(System.Collections.Generic.KeyValuePair<string, string> P in pValue.FParams) // Pridam vsetky parametre
            {
                FParams.Add(P.Key, P.Value);
            }
        }
        /// <summary>Vymazanie parametra</summary>
        /// <param name="pName">nazov parametra</param>
        public void Delete(string pName)
        {
            string N = pName.ToLower();
            if (FParams.ContainsKey(N)) FParams.Remove(N); // Vymazem
        }
        /// <summary>Test existencie parametra</summary>
        /// <param name="pName">nazov</param>
        /// <returns>true / false</returns>
        public bool Exists(string pName)
        {
            return FParams.ContainsKey(pName.ToLower()); // Hladam key
        }

        /// <summary>Serializacia obsahu do retazca</summary>
        /// <param name="pEncode">priznak zakodovania</param>
        /// <param name="pParamsSeparator">oddelovac parametrov</param>
        /// <param name="pValueSeparator">oddelovac nazvu a hodnoty</param>
        /// <returns>vysledok</returns>
        public string Serialize(bool pEncode = true, char pParamsSeparator = '\n', char pValueSeparator = '=')
        {
            try
            {
                System.Text.StringBuilder B = new System.Text.StringBuilder(); // Builder

                string P1 = pParamsSeparator.ToString(); string P2 = pValueSeparator.ToString();
                foreach (System.Collections.Generic.KeyValuePair<string, string> P in FParams)
                {
                    B.AppendFormat("{0}{1}{2}{3}", P.Key, P2, P.Value, P1); // Zaradim parameter
                }

                return pEncode ? ICore.Base64Encode(B.ToString()) : B.ToString(); // Zakodujem a vratim vysledok
            }
            catch
            {
                return ""; // Chyba
            }
        }
        /// <summary>Deserializacia objektu z retazca</summary>
        /// <param name="pData">serializovany obsah</param>
        /// <param name="pEncode">priznak zakodovaneho vstupu</param>
        /// <param name="pParamsSeparator">oddelovac parametrov</param>
        /// <param name="pValueSeparator">oddelovac nazvu a hodnoty</param>
        public void Deserialize(string pData, bool pEncode = true, char pParamsSeparator = '\n', char pValueSeparator = '=')
        {
            try
            {
                string Data = pEncode ? ICore.Base64Decode(pData) : pData; // Dekodujem vstup
                Clear(); // Vymazem aktualny obsah

                int I = 0;
                while (true)
                {
                    int I1 = Data.IndexOf(pParamsSeparator, I); // Hladam koniec parametra
                    string Line = I1 == -1 ? Data.Substring(I) : Data.Substring(I, I1 - I); // Extrahujem
                    if (!string.IsNullOrWhiteSpace(Line)) // Nie je prazdny?
                    {
                        int I2 = Line.IndexOf(pValueSeparator); // Hladam oddelovac hopdnoty
                        if (I2 == -1) SetParam(Line, ""); else SetParam(Line.Substring(0, I2), Line.Substring(I2 + 1)); // Zaradim parameter
                    }
                    if (I1 == -1) break; // Koniec?
                    I = I1 + 1; // Dalsi parameter
                }
            }
            catch
            {
                Clear(); // Chyba
            }
        }

        /// <summary>Ulozenie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pValue">hodnota</param>
        public void SetParam(string pName, string pValue)
        {
            string N = pName.ToLower(); // Kluc je malymi pismenami
            if (FParams.ContainsKey(N)) FParams[N] = pValue; // Ak existuje tak aktualizujem hodnotu
            else FParams.Add(N, pValue); // Inak zaradim novy parameter
        }
        /// <summary>Ulozenie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pValue">hodnota</param>
        public void SetParam(string pName, int pValue)
        {
            SetParam(pName, ICore.ToStr(pValue)); // Volam ulozenie
        }
        /// <summary>Ulozenie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pValue">hodnota</param>
        public void SetParam(string pName, uint pValue)
        {
            SetParam(pName, ICore.ToStr(pValue)); // Volam ulozenie
        }
        /// <summary>Ulozenie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pValue">hodnota</param>
        public void SetParam(string pName, long pValue)
        {
            SetParam(pName, ICore.ToStr(pValue)); // Volam ulozenie
        }
        /// <summary>Ulozenie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pValue">hodnota</param>
        public void SetParam(string pName, ulong pValue)
        {
            SetParam(pName, ICore.ToStr(pValue)); // Volam ulozenie
        }
        /// <summary>Ulozenie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pValue">hodnota</param>
        public void SetParam(string pName, double pValue)
        {
            SetParam(pName, ICore.Dbl2Str(pValue, 12)); // Volam ulozenie
        }
        /// <summary>Ulozenie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pValue">hodnota</param>
        public void SetParam(string pName, bool pValue)
        {
            SetParam(pName, (int)(pValue ? 1 : 0)); // Volam ulozenie
        }

        /// <summary>Ziskanie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pDefValue">prednastavena hodnota</param>
        /// <returns>aktualna alebo prednastavena hodnota</returns>
        public string GetParam(string pName, string pDefValue)
        {
            string N = pName.ToLower(); // Kluc je malymi pismenami
            if (FParams.ContainsKey(N)) return FParams[N]; // Ak existuje tak vratim aktualnu hodnotu
            else
            {
                FParams.Add(N, pDefValue); // Inak zaradim novy parameter
                return pDefValue;
            }
        }
        /// <summary>Ziskanie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pDefValue">prednastavena hodnota</param>
        /// <returns>aktualna alebo prednastavena hodnota</returns>
        public int GetParam(string pName, int pDefValue)
        {
            return ICore.ToInt(GetParam(pName, ICore.ToStr(pDefValue))); // Volam ziskanie hodnoty
        }
        /// <summary>Ziskanie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pDefValue">prednastavena hodnota</param>
        /// <returns>aktualna alebo prednastavena hodnota</returns>
        public uint GetParam(string pName, uint pDefValue)
        {
            return ICore.ToUInt(GetParam(pName, ICore.ToStr(pDefValue))); // Volam ziskanie hodnoty
        }
        /// <summary>Ziskanie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pDefValue">prednastavena hodnota</param>
        /// <returns>aktualna alebo prednastavena hodnota</returns>
        public long GetParam(string pName, long pDefValue)
        {
            return ICore.ToLong(GetParam(pName, ICore.ToStr(pDefValue))); // Volam ziskanie hodnoty
        }
        /// <summary>Ziskanie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pDefValue">prednastavena hodnota</param>
        /// <returns>aktualna alebo prednastavena hodnota</returns>
        public ulong GetParam(string pName, ulong pDefValue)
        {
            return ICore.ToULong(GetParam(pName, ICore.ToStr(pDefValue))); // Volam ziskanie hodnoty
        }
        /// <summary>Ziskanie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pDefValue">prednastavena hodnota</param>
        /// <returns>aktualna alebo prednastavena hodnota</returns>
        public double GetParam(string pName, double pDefValue)
        {
            return ICore.Str2Dbl(GetParam(pName, ICore.Dbl2Str(pDefValue, 12))); // Volam ziskanie hodnoty
        }
        /// <summary>Ziskanie hodnoty parametra</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pDefValue">prednastavena hodnota</param>
        /// <returns>aktualna alebo prednastavena hodnota</returns>
        public bool GetParam(string pName, bool pDefValue)
        {
            return GetParam(pName, (int)(pDefValue ? 1 : 0)) != 0; // Volam ziskanie hodnoty
        }
    }
}
